package org.example.mall.admin.controller.common;

import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.example.mall.admin.configuration.resource.Inner;
import org.example.mall.admin.util.R;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.Map;

/**
 * @author hzq
 * @date 2021/12/10 15:57
 */
@Api(tags = "认证中心")
@RestController
@AllArgsConstructor
public class TokenController {

    private final TokenStore tokenStore;
    private final TokenEndpoint tokenEndpoint;

    @ApiOperation("认证")
    @RequestMapping(value = "/oauth/token", method = RequestMethod.GET)
    public R<OAuth2AccessToken> getAccessToken(Principal principal, @RequestParam
            Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        ResponseEntity<OAuth2AccessToken> accessToken = tokenEndpoint.getAccessToken(principal, parameters);
        return R.ofSuccess(accessToken.getBody());
    }

    @ApiOperation("认证")
    @RequestMapping(value = "/oauth/token", method = RequestMethod.POST)
    public R<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam
            Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        ResponseEntity<OAuth2AccessToken> accessToken = tokenEndpoint.postAccessToken(principal, parameters);
        return R.ofSuccess(accessToken.getBody());
    }

    /**
     * 退出token
     *
     * @param authHeader Authorization
     */
    @Inner(false)
    @DeleteMapping("/token/logout")
    public R logout(@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authHeader) {
        if (StrUtil.isBlank(authHeader)) {
            return R.ofSuccess("退出失败，token 为空", Boolean.FALSE);
        }

        String tokenValue = authHeader.replace(OAuth2AccessToken.BEARER_TYPE, StrUtil.EMPTY).trim();

        return delToken(tokenValue);
    }

    /**
     * 令牌管理调用
     *
     * @param token token
     */
    @DeleteMapping("/token/{token}")
    public R<Boolean> delToken(@PathVariable("token") String token) {

        OAuth2AccessToken accessToken = tokenStore.readAccessToken(token);
        if (accessToken == null || StrUtil.isBlank(accessToken.getValue())) {
            return R.ofSuccess("退出失败，token为空！", Boolean.TRUE);
        }

        // 清空access token
        tokenStore.removeAccessToken(accessToken);

        // 清空 refresh token
        OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
        tokenStore.removeRefreshToken(refreshToken);

        return R.ofSuccess("退出成功", Boolean.TRUE);
    }
}
